package com.example.beautymakeup.service.impl;

import com.example.beautymakeup.dao.AdminDao;
import com.example.beautymakeup.domain.Code;
import com.example.beautymakeup.domain.Result;
import com.example.beautymakeup.domain.entry.LoginUser;
import com.example.beautymakeup.pojo.Admin;
import com.example.beautymakeup.pojo.User;
import com.example.beautymakeup.service.LoginService;
import com.example.beautymakeup.service.UserService;
import com.example.beautymakeup.utils.JwtUtil;
import com.example.beautymakeup.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;

@Service
public class LoginServiceImpl implements LoginService {

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;

    @Autowired
    private UserService userService;

    @Autowired
    private AdminDao adminDao;

    @Autowired
    private RedisCache redisCache;

    @Override
    public Result login(String code) {

//      过滤不符合长度的code
        if (code.length() != 32){
            return new Result(Code.GET_ERR,"无效code");
        }
//      过滤含有特殊字符的code
        String pattern = "[^a-zA-Z0-9]";
        // 判断字符串是否匹配正则表达式
        boolean containsSpecialChar = Pattern.compile(pattern).matcher(code).find();
        // 输出结果
        if (containsSpecialChar) {
            return new Result(Code.GET_ERR,"无效code");
        }


        String urlBuilder = "https://api.weixin.qq.com/sns/jscode2session";
        String query = "appid=" + URLEncoder.encode(appid, StandardCharsets.UTF_8) +
                "&secret=" + URLEncoder.encode(secret, StandardCharsets.UTF_8) +
                "&js_code=" + URLEncoder.encode(code, StandardCharsets.UTF_8) +
                "&grant_type=authorization_code";
        String fullUrl = urlBuilder + "?" + query;



        try {
            URL url = new URL(fullUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod("POST");

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                StringBuilder response = new StringBuilder();

                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();

                String jsonResponse = response.toString();
                String openId = jsonResponse.split("\"openid\":\"")[1].split("\"")[0];
//                String session_key = jsonResponse.split("\"session_key\":\"")[1].split("\",\"")[0];

                User byOpenId = userService.getByOpenId(openId);
//                注册
                if (byOpenId == null) {
                    Random rand = new Random();
                    int randomNumber = rand.nextInt(9000) + 1000;
                    User user = new User();
                    user.setOpenId(openId);
                    user.setUserName("微信用户" + randomNumber);
                    user.setUserImage("https://apieleme.oss-cn-guangzhou.aliyuncs.com/newImage.jpg");
                    boolean save = userService.save(user);
                    if (save){
                        User loginUser = userService.getByOpenId(openId);
                        LoginUser login = new LoginUser();
                        login.setUserName(loginUser.getUserName());
                        login.setUserImage(loginUser.getUserImage());
                        String uid = String.valueOf(loginUser.getUid());
                        String jwt = JwtUtil.createJWT(uid, JwtUtil.JWT_TTL);
                        Map<String ,String> map = new HashMap<>();
                        map.put("token",jwt);
                        map.put("data", String.valueOf(login));
                        redisCache.setCacheObject("login:"+uid,login);
                        return new Result(Code.GET_OK,"登陆成功",map);
                    }else{
                        return new Result(Code.GET_ERR,"数据库错误");
                    }
                }
//                登录
                if (byOpenId != null){
                    if (byOpenId.getStatus() != 0){
                        return new Result(Code.LOGIN_ERR, "账号已被封禁,请联系管理员");
                    }
                    LoginUser login = new LoginUser();
                    login.setUserName(byOpenId.getUserName());
                    login.setUserImage(byOpenId.getUserImage());
                    String uid = String.valueOf(byOpenId.getUid());
                    String jwt = JwtUtil.createJWT(uid, JwtUtil.JWT_TTL);
                    Map<String ,String> map = new HashMap<>();
                    map.put("token",jwt);
                    map.put("userName",byOpenId.getUserName());
                    map.put("userImage",byOpenId.getUserImage());
                    redisCache.setCacheObject("login:"+uid,login);
                    return new Result(Code.GET_OK,"登陆成功",map);
                }else {
                    return new Result(Code.GET_ERR,"数据库错误");
                }
            } else {
                // 处理请求失败的情况
                return new Result(Code.GET_ERR, "请求微信登录接口失败，响应码：" + responseCode);
            }
        } catch (Exception e) {
            // 处理网络请求异常
            return new Result(Code.GET_ERR, "请求微信登录接口发生异常：" + e.getMessage());
        }
    }

    @Override
    public Result admin(Admin admin) {
        Admin login = adminDao.login(admin);
        if (login != null){
            String jwt = JwtUtil.createJWT("admin");
            return new Result(Code.GET_OK,"登陆成功",jwt);
        }
        return new Result(Code.GET_ERR,"登陆失败");
    }

    @Override
    public Result logout(String token) throws Exception {
        String subject = JwtUtil.parseJWT(token).getSubject();
        if ("admin".equals(subject)){
            return new Result<>(Code.LOGIN_OK,"登出成功");
        }else{
            String s = "login:" + subject;
            boolean b = redisCache.deleteObject(s);
            if (b){
                return new Result<>(Code.LOGIN_OK,"登出成功");
            }else{
                return new Result<>(Code.LOGIN_ERR,"登出失败");
            }
        }
    }
}
